#include <iostream>

// #include "1.h"
using namespace std;

template <typename T1, typename T2>
void Func(T1 a, T2 b) {
  cout << "函数模板, this is void Func(T1 a, T2 b)" << endl;
  cout << a << ", " << b << endl;
}

// 函数模板没有偏特化，因为那就是函数模板的重载
template <typename T1>
// void Func<int, T1>(int a, T1 b) {  // function template partial
// specialization is not allowed
void Func(int a, T1 b) {
  cout << "函数模板的重载, this is void Func(int a, T1 b)" << endl;
  cout << a << ", " << b << endl;
}
// TODO:标签分发

// 函数模板的全特化
template <>
void Func(int a, int b) {
  cout << "函数模板的全特化, this is void Func(int a, int b)" << endl;
  cout << a << ", " << b << endl;
}
void Test1() {
  Func(3, 0.435);
  Func(0.432, 0.543);
  Func(3, 56);
}
template <typename T1, typename T2>
class XXX {
 public:
  XXX() { cout << "template <typename T1, typename T2> XXX construct" << endl; }

 private:
  T1 a;
  T2 b;
};
// 偏特化
template <typename T2>
class XXX<int, T2> {
 public:
  XXX() { cout << "template <typename T2> XXX construct" << endl; }

 private:
  int a;
  T2 b;
};

// 全特化
template <>
class XXX<int, int> {
 public:
  XXX() { cout << "template <> XXX construct" << endl; }

 private:
  int a;
  int b;
};
void Test2() {
  XXX<double, double> a;
  XXX<int, double> b;
  XXX<int, int> c;
}
// 可变长度数组
template <typename T, unsigned N>
class Array {
 public:
  // ......
 private:
  T data_[N];
};
// 编译期求数组长度
template <typename T, unsigned N>
unsigned Sizeof(T (&a)[N]) {
  return N;
}
void Test3() {
  int a[20];
  cout << Sizeof(a) << endl;
}
int main() {
  Test1();
  Test2();
  Test3();
  return 0;
}
// TODO:函数模板全特化、偏特化与函数模板重载的关系
// TODO:使用指针的偏特化